package com.effectiv.crm.service.impl;

import java.util.List;

import javax.inject.Named;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import com.effectiv.crm.domain.FileUploadDetails;
import com.effectiv.crm.etl.api.ExtractStrategy;
import com.effectiv.crm.etl.api.LoadStrategy;
import com.effectiv.crm.etl.api.TransformStrategy;
import com.effectiv.crm.service.api.ImportService;

@Named
@Slf4j
public class ImportServiceImpl implements ImportService {

	private final String acceptedTypes[] = { "text/comma-separated-values",
			"text/csv", "application/csv" };

	@Autowired
	private List<ExtractStrategy> extractStragies;

	@Autowired
	private List<TransformStrategy> tranformStragies;

	@Autowired
	private List<LoadStrategy> loadStragies;

	@Async
	public void process(FileUploadDetails fileDetails, Class c) {

		log.info("Starting file import process.");
		log.info("Extract strategy - {}", extractStragies);

		// extract
		List extractedData = null;

		for (ExtractStrategy es : extractStragies) {
			if (es.canExtract(fileDetails)) {
				extractedData = es.extract(fileDetails, c);
				break;
			}
		}

		// transform
		List transformedData = null;

		for (TransformStrategy ts : tranformStragies) {
			if (ts.canTransform(fileDetails)) {
				transformedData = ts.transform(extractedData, fileDetails, c);
				break;
			}
		}
		
		///load
		for(LoadStrategy ls : loadStragies){
			if(ls.canLoad(fileDetails, c)){
				ls.load(transformedData, fileDetails, c);
				break;
			}
		}
	}

	public void preProcess(FileUploadDetails fileDetails, Class c) {
		if (validateFileSize(fileDetails)) {
			throw new RuntimeException("Empty file cannot be uploaded.");
		}

		if (validateFileType(fileDetails)) {
			throw new RuntimeException(
					"Invalid file type.Only csv files allowed.");
		}
	}

	protected boolean validateFileType(FileUploadDetails fileDetails) {
		return StringUtil.equalsOneIgnoreCase(fileDetails.getContentType(),
				acceptedTypes) == -1;

	}

	protected boolean validateFileSize(FileUploadDetails fileDetails) {
		return fileDetails.getSize() == 0;
	}
}
